package com.societyGames.codeAlong.state.codeExercise.model
{
/*Error
	at com.societyGames.codeAlong.state.codeExercise.view::EditorView/executeClickHandler()[G:\Projects\CodeAlong\CodeAlong\src\com\societyGames\codeAlong\state\codeExercise\view\EditorView.as:99]
		at com.societyGames.flashForms::ThreeStateButton/internalClickHandler()[G:\Projects\CodeAlong\CodeAlong\src\com\societyGames\userInterface\ThreeStateButton.as:49]*/

/*Error: Test Message
	at com.societyGames.codeAlong.state.codeExercise.view::EditorView/executeClickHandler()[G:\Projects\CodeAlong\CodeAlong\src\com\societyGames\codeAlong\state\codeExercise\view\EditorView.as:99]
		at com.societyGames.flashForms::ThreeStateButton/internalClickHandler()[G:\Projects\CodeAlong\CodeAlong\src\com\societyGames\userInterface\ThreeStateButton.as:49]*/
	
/*Error:
	at com.societyGames.codeAlong.state.codeExercise.view::EditorView/executeClickHandler()[G:\Projects\CodeAlong\CodeAlong\src\com\societyGames\codeAlong\state\codeExercise\view\EditorView.as:99]
	at com.societyGames.flashForms::ThreeStateButton/internalClickHandler()[G:\Projects\CodeAlong\CodeAlong\src\com\societyGames\userInterface\ThreeStateButton.as:49]*/

	
/*ReferenceError: Error #1065: Variable blah is not defined.
	at global$init()[main:2]*/

	public class StackTraceMessage
	{
		private var _exceptionType:String;
		private var _errorId:int = 0;
		private var _errorText:String;
		private var _calls:Vector.<StackTraceCallMessage> = new Vector.<StackTraceCallMessage>();
		
		//Gets the first part of the error text.
		public function messageToString():String
		{
			var text:String = this._exceptionType;
			if (this._errorId != 0)
			{
				text += ": Error #" + this._errorId.toString();
			}
			if (_errorText != null)
			{
				text += ":" + this._errorText;
			}
			return text;
		}
		
		//Gets the entire text.
		public function toString():String
		{
			var text:String = messageToString();
			for each (var call:StackTraceCallMessage in this._calls)
			{
				text += "\n" + call.toString();
			}
			return text;
		}
		
		public static function fromString(text:String):StackTraceMessage
		{
			//Split it into lines.
			var textParts:Array /*String*/ = text.split("\n");
			if (textParts.length == 0)
			{
				throw new ArgumentError("Invalid text.");
			}
			
			//Our return value.
			var message:StackTraceMessage = new StackTraceMessage();
			
			//Parse the first line.
			var exceptionParts:Array /*string*/ = textParts[0].split(":");
			if (exceptionParts.length == 0)
			{
				throw new ArgumentError("Invalid text.");
			}
			message._exceptionType = exceptionParts[0];
			if (exceptionParts.length > 1)
			{
				if (String(exceptionParts[1]).indexOf(" Error #") == 0)
				{
					var errorIdParts:Array = exceptionParts[1].split("#");
					if (errorIdParts.length != 2)
					{
						throw new ArgumentError("Invalid text.");
					}
					message._errorId = int(errorIdParts[1]);
				}
				else
				{
					message._errorText = exceptionParts[1];	
				}
			}
			if (exceptionParts.length > 2)
			{
				message._errorText = exceptionParts[2];
			}

			//Parse remaining stack lines.
			for (var index:int = 1; index < textParts.length; index++)
			{
				message._calls.push(StackTraceCallMessage.fromString(textParts[index]));
			}
			return message; 
		}
		
		public function get exceptionType():String
		{
			return _exceptionType;
		}

		public function get errorId():int
		{
			return _errorId;	
		}
		
		public function get errorText():String
		{		
			return _errorText;
		}
		
		public function get calls():Vector.<StackTraceCallMessage>
		{
			return this._calls;			
		}
	}
}
